iT邦幫忙

2022 iThome 鐵人賽

DAY 26
1
Modern Web

我與 Blazor 的 30 天系列 第 26

ASP.NET Core Blazor 系列 - 026 內建 Razor 元件 (3) DynamicComponent

  • 分享至 

  • xImage
  •  

前言

本篇文章同步發表於 個人部落格 Jim's Blog

DynamicComponent 顧名思義就是動態元件,允許開發者依照邏輯去動態的轉譯需要的元件,這篇文章會介紹該如何使用

基本使用


建立四個 Component

  1. One.razor
<h3>One</h3>

@code {

}
  1. Two.razor
<h3>Two</h3>

@code {

}
  1. Three.razor
<h3>Three</h3>

@code {

}
  1. DynamicComponentExample.razor
@page "/DynamicComponentExample"
<h3>DynamicComponentExample</h3>
<select @onchange="OnDropdownChange">
    <option value="">Select a value</option>
    <option value="@nameof(One)">第一個元件</option>
    <option value="@nameof(Two)">第二個元件</option>
    <option value="@nameof(Three)">第三個元件</option>
</select>

@if (selectedType is not null)
{
    <div class="border border-primary my-1 p-1">
        <DynamicComponent Type="@selectedType" />
    </div>
}
@code {
    private Type? selectedType;

    private void OnDropdownChange(ChangeEventArgs e)
    {
        selectedType = e.Value?.ToString()?.Length > 0 ? Type.GetType($"BlazorApp1.Pages.{e.Value}") : null;
    }
}

Type.GetType($"BlazorApp1.Pages.{e.Value}") 內的 Type.GetType 需要填入專案的命名空間

完成後的效果如下,會按照選取的類型去動態轉譯元件

動態轉譯需要參數的元件

和上面的步驟相同只有兩個地方做異動

  1. One.razor
    加入一個由外部傳入的參數
<h3>One</h3>
<p>@Content</p>
@code {
    [Parameter]
    public string Content { get; set; }
}

  1. DynamicComponentExample.razor
    動態轉譯時提供參數,元件參數需要以 IDictionary<string, object> string 是參數名稱 object 則是參數的值
@page "/DynamicComponentExample"
<h3>DynamicComponentExample</h3>
<select @onchange="OnDropdownChange">
    <option value="">Select a value</option>
    <option value="@nameof(One)">第一個元件</option>
    <option value="@nameof(Two)">第二個元件</option>
    <option value="@nameof(Three)">第三個元件</option>
</select>

@if (selectedType is not null)
{
    <div class="border border-primary my-1 p-1">
        <DynamicComponent Type="@selectedType"  Parameters="@components[selectedType.Name].Parameters" />
    </div>
}
@code {
    private Type? selectedType;

    public class ComponentMetadata
    {
        public string? Name { get; set; }
        public Dictionary<string, object> Parameters { get; set; } = new();
    }

    private Dictionary<string, ComponentMetadata> components = new()
    {
        {
            nameof(One), new ComponentMetadata() { Parameters = new Dictionary<string, object> { { "Content", "我是參數內容" } } }
        },
        {
            nameof(Two), new ComponentMetadata()
        },
        {
            nameof(Three), new ComponentMetadata()
        }
    };

    private void OnDropdownChange(ChangeEventArgs e)
    {
        selectedType = e.Value?.ToString()?.Length > 0 ? Type.GetType($"BlazorApp1.Pages.{e.Value}") : null;
    }

}

## 動態轉譯有實作事件回呼的元件

最後來展示有實作 EventCallback 的元件

  1. One.razor
<h3>One</h3>
<button @onclick="OnClickCallback">
    按我
</button>
@code {
    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
  1. DynamicComponentExample.razor
@page "/DynamicComponentExample"
<h3>DynamicComponentExample</h3>
<select @onchange="OnDropdownChange">
    <option value="">Select a value</option>
    <option value="@nameof(One)">第一個元件</option>
    <option value="@nameof(Two)">第二個元件</option>
    <option value="@nameof(Three)">第三個元件</option>
</select>
<p>@message</p>

@if (selectedType is not null)
{
    <div class="border border-primary my-1 p-1">
        <DynamicComponent Type="@selectedType" Parameters="@Components[selectedType.Name].Parameters" />
    </div>
}
@code {
    private Type? selectedType;
    private void CallbackMessage(MouseEventArgs e) => message = $"{DateTime.Now}";
    private string? message;

    public class ComponentMetadata
    {
        public string? Name { get; set; }
        public Dictionary<string, object> Parameters { get; set; } = new();
    }

    private Dictionary<string, ComponentMetadata> Components => new Dictionary<string, ComponentMetadata>()
    {
        {
            nameof(One),
            new ComponentMetadata
            {
                Name = nameof(One),
                Parameters =
                    new Dictionary<string, object>
                    {
                        {
                            "OnClickCallback",
                            EventCallback.Factory.Create<MouseEventArgs>(
                                this, CallbackMessage)
                        }
                    }
            }
        },
        {
            nameof(Two),new ComponentMetadata()
        },
        {
            nameof(Three),new ComponentMetadata()
        }
    };

    private void OnDropdownChange(ChangeEventArgs e)
    {
        selectedType = e.Value?.ToString()?.Length > 0 ? Type.GetType($"BlazorApp1.Pages.{e.Value}") : null;
    }

}

選擇第一個元件

點選按我按鈕

小結

在這一篇文章中,我們學習了怎麼使用動態轉譯元件,並且處理有參數的元件以及處理有參數是事件回呼的原件,有了動態轉譯可以讓 Blazor 開發上有更多的彈性


上一篇
ASP.NET Core Blazor 系列 - 025 內建 Razor 元件 (2) CascadingValue
下一篇
ASP.NET Core Blazor 系列 - 027 內建 Razor 元件 (4) Virtualize
系列文
我與 Blazor 的 30 天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言